//
// Created by user on 2025/7/31.
//

#ifndef HELLOC_SEMAPHORE_H
#define HELLOC_SEMAPHORE_H

#include "systemc"
using namespace sc_core;

class Semaphore : public sc_module {
public:
    sc_semaphore s;

    Semaphore(sc_module_name name, int sem) : sc_module(name), s(sem) {
        SC_THREAD(thread_1);
        SC_THREAD(thread_2);
        SC_THREAD(thread_3);
    }

    void thread_1(){
        while(true){
            if(s.trywait() == -1){
                s.wait();
            }
            std::cout<< sc_time_stamp() << ": locked by thread_1, value is "<< s.get_value() << std::endl;
            wait(1, SC_SEC);
            s.post();
            std::cout<< sc_time_stamp() << ": unlocked by thread_1, value is "<< s.get_value() << std::endl;
            wait(SC_ZERO_TIME);
        }
    }
    void thread_2(){
        while(true){
            if(s.trywait() == -1){
                s.wait();
            }
            std::cout<< sc_time_stamp() << ": locked by thread_2, value is "<< s.get_value() << std::endl;
            wait(1, SC_SEC);
            s.post();
            std::cout<< sc_time_stamp() << ": unlocked by thread_2, value is "<< s.get_value() << std::endl;
            wait(SC_ZERO_TIME);
        }
    }
    void thread_3(){
        while(true){
            if(s.trywait() == -1){
                s.wait();
            }
            std::cout<< sc_time_stamp() << ": locked by thread_3, value is "<< s.get_value() << std::endl;
            wait(1, SC_SEC);
            s.post();
            std::cout<< sc_time_stamp() << ": unlocked by thread_3, value is "<< s.get_value() << std::endl;
            wait(SC_ZERO_TIME);
        }
    }

};

#endif //HELLOC_SEMAPHORE_H
